/*
 *  ExperimetalCompose.cpp
 *  SoundController0002
 *
 *  Created by jiro on 10/09/26.
 *  Copyright 2010 jiro music. All rights reserved.
 *
 */

#include "ExperimetalCompose.h"
#include "../sc/SoundController.h"
#include <vector>
#include <iostream>

using namespace sc;
using namespace std;

void ExperimetalComposer::Compose_Botu( const std::string& folderPath )
{
	const double swell = 2 / 1.5;
	const double maxDynamics = 0.2;
	double length = -1;
	double time = 0;
	AudioRecorder32 recorder( 2, 1 );

	// 1st part
	{
		length = swell / 4;
		length = 1.5 / 2;

		double noteHzs[] = {
			WellTemperament::GetFrequency( Note::A, 0 ),
			WellTemperament::GetFrequency( Note::B, 0 ),
			WellTemperament::GetFrequency( Note::C, 0 ),
			WellTemperament::GetFrequency( Note::D, 0 ),
			WellTemperament::GetFrequency( Note::E, 0 ),
			WellTemperament::GetFrequency( Note::F, 0 ),
			WellTemperament::GetFrequency( Note::G, 0 ),
			WellTemperament::GetFrequency( Note::A, 1 )
		};
		const int count = sizeof( noteHzs ) / sizeof( double );
		for ( int i = 0; i < count; i++ ) {
			std::cout << noteHzs[ i ] << "\n";

			const SoundElement32* element = SoundGenerator::Generate( noteHzs[ i ], length, maxDynamics );			
			recorder.Record( 0, 0, time, element, 0.5, 0.5 );
			
			const SoundElement32* element_ = SoundGenerator::Generate( noteHzs[ i ] + swell, length, maxDynamics );
			recorder.Record( 0, 0, time, element_, 0.5, 0.5 );

			time += length;
		}		
	}

	recorder.OutputAudioFile( folderPath + "new_ideas.wav" );
}

void ExperimetalComposer::Compose( const std::string& folderPath )
{
	const double swell = 0.8;
	const double maxDynamics = 0.2;
	double length = -1;
	double time = 0;
	AudioRecorder32 recorder( 2, 1 );
 
	// 1st part
	{
		length = 10 * ( 3.0 / 2.0 );
		const double noteHz_1st = WellTemperament::GetFrequency( Note::C, -1 );
		const double noteHz_2nd = WellTemperament::GetFrequency( Note::F, -2 );
		const double noteHz_1st_ = WellTemperament::GetFrequency( Note::C, -1 ) + swell;
		const double noteHz_2nd_ = WellTemperament::GetFrequency( Note::F, -2 ) + ( 2.0 / 3.0 ) * swell;

		const SoundElement32* element_1st = SoundGenerator::Generate( noteHz_1st, length, maxDynamics ); 
		const SoundElement32* element_2nd = SoundGenerator::Generate( noteHz_2nd, length, maxDynamics ); 
		const SoundElement32* element_1st_ = SoundGenerator::Generate( noteHz_1st_, length, maxDynamics ); 
		const SoundElement32* element_2nd_ = SoundGenerator::Generate( noteHz_2nd_, length, maxDynamics ); 

		for ( int i = 0; i < 4; i++ ) {
			recorder.Record( 0, 0, time, element_1st, 0.5, 0.5 );
			recorder.Record( 0, 0, time, element_2nd, 0.5, 0.5 );
			recorder.Record( 0, 0, time, element_1st_, 0.5, 0.5 );
			recorder.Record( 0, 0, time, element_2nd_, 0.5, 0.5 );
			time += length;
		}
	}

	time = length;
	
	//	2nd part
	{ 
		length = 2.0 / 3.0;
		const double noteHz_1st = WellTemperament::GetFrequency( Note::G, -1 );
		const double noteHz_2nd = WellTemperament::GetFrequency( Note::D, 0 );
		const double noteHz_1st_ = WellTemperament::GetFrequency( Note::G, -1 ) + swell;
		const double noteHz_2nd_ = WellTemperament::GetFrequency( Note::D, 0 ) + ( 2.0 / 3.0 ) * swell;
		
		const SoundElement32* element_1st = SoundGenerator::Generate( noteHz_1st, length, maxDynamics ); 
		const SoundElement32* element_2nd = SoundGenerator::Generate( noteHz_2nd, length, maxDynamics ); 
		const SoundElement32* element_1st_ = SoundGenerator::Generate( noteHz_1st_, length, maxDynamics ); 
		const SoundElement32* element_2nd_ = SoundGenerator::Generate( noteHz_2nd_, length, maxDynamics ); 

		for ( int i = 0; i < 4; i++ ) {
			recorder.Record( 0, 0, time, element_1st, 0.5, 0.5 );
			recorder.Record( 0, 0, time, element_2nd, 0.5, 0.5 );
			recorder.Record( 0, 0, time, element_1st_, 0.5, 0.5 );
			recorder.Record( 0, 0, time, element_2nd_, 0.5, 0.5 );
			time += length;
		}
	}

	time = length;
	//	2nd part
	{ 
		length = 2.0 / 3.0;
		const double noteHz_1st = WellTemperament::GetFrequency( Note::F, -1 );
		const double noteHz_2nd = WellTemperament::GetFrequency( Note::A, 0 );
		const double noteHz_1st_ = WellTemperament::GetFrequency( Note::F, -1 ) + swell;
		const double noteHz_2nd_ = WellTemperament::GetFrequency( Note::A, 0 ) + ( 5.0 / 2.0 ) * swell;
		
		const SoundElement32* element_1st = SoundGenerator::Generate( noteHz_1st, length, maxDynamics ); 
		const SoundElement32* element_2nd = SoundGenerator::Generate( noteHz_2nd, length, maxDynamics ); 
		const SoundElement32* element_1st_ = SoundGenerator::Generate( noteHz_1st_, length, maxDynamics ); 
		const SoundElement32* element_2nd_ = SoundGenerator::Generate( noteHz_2nd_, length, maxDynamics ); 

		for ( int i = 0; i < 4; i++ ) {
			recorder.Record( 0, 0, time, element_1st, 0.5, 0.5 );
			recorder.Record( 0, 0, time, element_2nd, 0.5, 0.5 );
			recorder.Record( 0, 0, time, element_1st_, 0.5, 0.5 );
			recorder.Record( 0, 0, time, element_2nd_, 0.5, 0.5 );
			time += length;
		}
	}
	
	recorder.OutputAudioFile( folderPath + "new_idea.wav" );

}

void ExperimetalComposer::Compose02( const std::string& folderPath )
{
	SubCompose_001( folderPath );
//	SubCompose_000( "" );
}

void ExperimetalComposer::SubCompose_000( const std::string& path )
{
	double swell = 0.0;
	double length = -1;
	double time = 0;
	int noteCount = 0;
	TimeController controller( 60.0, 4, 4 );

	{	//	base part, 1 ~ 6 bars
		swell = controller.GetNoteSwell( TimeController::WholeNote );
		AudioRecorder32 recorder( 2, 1 );
		length = 24;
		time = 0;
		std::vector< double > freqs( 2 );
		freqs[ 0 ] = WellTemperament::GetFrequency( Note::C_2 );
		freqs[ 1 ] = freqs[ 0 ] + swell;
//		freqs[ 2 ] = 2 * freqs[ 0 ];
		std::vector< const SoundElement32* > chord = SoundGenerator::GenerateChord( freqs, length, 0.2 );
		recorder.Record( 0, 0, time, chord, 0.5, 0.5 );
		recorder.OutputAudioFile( path + "cmps0010_low.wav" );
	}

	{
		swell = controller.GetNoteSwell( TimeController::HalfNote );
		AudioRecorder32 recorder( 2, 1 );
		length = 6;
		time = 0;
		std::vector< double > freqs( 2 );
		freqs[ 0 ] = WellTemperament::GetFrequency( Note::F_1 );
		freqs[ 1 ] = freqs[ 0 ] + swell;
//		freqs[ 2 ] = 2 * freqs[ 0 ];
		std::vector< const SoundElement32* > chord = SoundGenerator::GenerateChord( freqs, length, 0.2 );
		recorder.Record( 0, 0, time, chord, 0.5, 0.5 );
		recorder.OutputAudioFile( path + "cmps0010_low_2.wav" );
	}

	{
		swell = controller.GetNoteSwell( TimeController::WholeNote );
		AudioRecorder32 recorder( 2, 1 );
		length = 6;	
		time = 0;
		std::vector< double > freqs( 2 );
		freqs[ 0 ] = WellTemperament::GetFrequency( Note::A_1 );
		freqs[ 1 ] = freqs[ 0 ] + swell;
//		freqs[ 2 ] = 2 * freqs[ 0 ];
		std::vector< const SoundElement32* > chord = SoundGenerator::GenerateChord( freqs, length, 0.2 );
		recorder.Record( 0, 0, time, chord, 0.5, 0.5 );
		recorder.OutputAudioFile( path + "cmps0010_low_3.wav" );
	}

	{
		noteCount = 2;
		swell = controller.GetNoteSwell( TimeController::HalfNoteTriplet );
		AudioRecorder32 recorder( 2, 1 );
		length = 1;
		time = 0;
		std::vector< double > freqs( noteCount );
		freqs[ 0 ] = WellTemperament::GetFrequency( Note::D_3 );
		freqs[ 1 ] = freqs[ 0 ] + swell;
		std::vector< const SoundElement32* > chord = SoundGenerator::GenerateChord( freqs, length, 0.2 );
		recorder.Record( 0, 0, time, chord, 0.5, 0.5 );

		time += length;
		freqs[ 0 ] = WellTemperament::GetFrequency( Note::G_3 );
		freqs[ 1 ] = freqs[ 0 ] + swell;
		chord = SoundGenerator::GenerateChord( freqs, length, 0.2 );
		recorder.Record( 0, 0, time, chord, 0.5, 0.5 );

		recorder.OutputAudioFile( path + "cmps0010_high.wav" );
	}

	{
		swell = controller.GetNoteSwell( TimeController::HalfNoteTriplet );
		AudioRecorder32 recorder( 2, 1 );
		int noteCount = 2;
		length = 2;
		time = 0;
		std::vector< double > freqs( noteCount );
		freqs[ 0 ] = WellTemperament::GetFrequency( Note::D_5 );
		freqs[ 1 ] = freqs[ 0 ] + swell;
//		freqs[ 2 ] = WellTemperament::GetFrequency( Note::A_5 );
		std::vector< const SoundElement32* > chord = SoundGenerator::GenerateChord( freqs, length, 0.15 );
		recorder.Record( 0, 0, time, chord, 0.5, 0.5 );
		recorder.OutputAudioFile( path + "cmps0010_high_2.wav" );
	}
	
	{
	    const WaveTable& dynamicsTable = WaveTableFactory::Create( WaveTable::Type_Sine, 0.5 );
		const WaveTable& soundTable = WaveTableFactory::Create( WaveTable::Type_Sine, 440 );
		double time = 1;

		const SoundElement32* element = 
			SoundElementFactory32::Create( soundTable, dynamicsTable, time );

		AudioRecorder32 recorder( 2, 1 );
		recorder.Record( 0, 0, 0.0, element, 0.5, 0.5 );
		recorder.OutputAudioFile( path + "wtwdt.wav" );		
	}

	{
		std::vector< double > freqs( 2 );
		freqs[ 0 ] = WellTemperament::GetFrequency( Note::D_5 );
		freqs[ 1 ] = freqs[ 0 ] + swell;
		const SoundElement32* element = SoundGenerator::GenerateWithDynamicsTable( 441, 2 );

		AudioRecorder32 recorder( 2, 1 );
		recorder.Record( 0, 0, 0.0, element, 0.5, 0.5 );
		recorder.OutputAudioFile( path + "wtwdt2.wav" );
	}

	{
		noteCount = 2;
		swell = controller.GetNoteSwell( TimeController::HalfNoteTriplet );
		AudioRecorder32 recorder( 2, 1 );
		length = 3;
		time = 0;
		std::vector< double > freqs( noteCount );
		freqs[ 0 ] = WellTemperament::GetFrequency( Note::D_3 );
		freqs[ 1 ] = WellTemperament::GetFrequency( Note::DSharp_4 );
		std::vector< const SoundElement32* > chord = SoundGenerator::GenerateChordWithDynamicsTable( freqs, length, 0.2 );
		recorder.Record( 0, 0, time, chord, 0.5, 0.5 );
		recorder.OutputAudioFile( path + "wtwdt3.wav" );
	}

	{
		noteCount = 4;
		swell = controller.GetNoteSwell( TimeController::HalfNoteTriplet );
		AudioRecorder32 recorder( 2, 1 );
		length = 1;
		time = 0;
		std::vector< double > freqs( noteCount );
		std::vector< const SoundElement32* > chord;
		double adjuster = 0.2;

		// chord
		freqs[ 0 ] = WellTemperament::GetFrequency( Note::B_2 );
		freqs[ 1 ] = WellTemperament::GetFrequency( Note::FSharp_3 );
		freqs[ 2 ] = WellTemperament::GetFrequency( Note::D_4 );
		freqs[ 3 ] = WellTemperament::GetFrequency( Note::A_4 );
		
		chord = SoundGenerator::GenerateChordWithDynamicsTable( freqs, length, adjuster );
		recorder.Record( 0, 0, time, chord, 0.5, 0.5 );

		time += length;
		freqs[ 0 ] = WellTemperament::GetFrequency( Note::C_3 );
		freqs[ 1 ] = WellTemperament::GetFrequency( Note::G_3 );
		freqs[ 2 ] = WellTemperament::GetFrequency( Note::D_4 );
		freqs[ 3 ] = WellTemperament::GetFrequency( Note::B_4 );
		chord = SoundGenerator::GenerateChordWithDynamicsTable( freqs, length, adjuster );
		recorder.Record( 0, 0, time, chord, 0.5, 0.5 );

		time += length;
		freqs[ 0 ] = WellTemperament::GetFrequency( Note::A_2 );
		freqs[ 1 ] = WellTemperament::GetFrequency( Note::E_3 );
		freqs[ 2 ] = WellTemperament::GetFrequency( Note::B_3 );
		freqs[ 3 ] = WellTemperament::GetFrequency( Note::FSharp_4 );
		chord = SoundGenerator::GenerateChordWithDynamicsTable( freqs, length, adjuster );
		recorder.Record( 0, 0, time, chord, 0.5, 0.5 );

		time += length;
		freqs[ 0 ] = WellTemperament::GetFrequency( Note::C_3 );
		freqs[ 1 ] = WellTemperament::GetFrequency( Note::G_3 );
		freqs[ 2 ] = WellTemperament::GetFrequency( Note::D_4 );
		freqs[ 3 ] = WellTemperament::GetFrequency( Note::E_4 );
		chord = SoundGenerator::GenerateChordWithDynamicsTable( freqs, length, adjuster );
		recorder.Record( 0, 0, time, chord, 0.5, 0.5 );

		recorder.OutputAudioFile( path + "wtwdt4.wav" );
	}
	
	{
		const SoundElement32* element;

		// melody 
		AudioRecorder32 recorder( 2, 1 );
		time = 0.0;
		length = 1.0 / 3.0;
		Note::MidiNumber notes[] = { 
			Note::B_4, Note::CSharp_5, Note::FSharp_5, 
			Note::B_5, Note::A_5, Note::D_5,
			Note::CSharp_5, Note::FSharp_5, Note::B_4,
			Note::B_4, Note::D_5, Note::E_5,
		};

		for ( int i = 0; i < sizeof ( notes ) / sizeof( Note::MidiNumber ); i++ ) {
			element = SoundGenerator::GenerateWithDynamicsTable( WellTemperament::GetFrequency( notes[ i ] ), length, 0.5 );
			recorder.Record( 0, 0, time, element, 0.5, 0.5 );
			time += length;
		}		
		recorder.OutputAudioFile( path + "wtwdt5.wav" );
	}

	{
		time = 0;
		length = 1.0;
		double powerOfX = 2.8;
		double adjuster = 0.5;
		AudioRecorder32 recorder( 2, 1 );
		const WaveFunction& func = WaveFunctionFactory::CreateXSinX( powerOfX, 2 * length );
		const WaveTable& dynamicsTable = WaveTableFactory::Create( func, adjuster );
		const WaveTable& soundTable = WaveTableFactory::Create( WaveTable::Type_Sine, 440, 1 );
		const SoundElement32* element = SoundElementFactory32::Create( soundTable, dynamicsTable, length );

		for ( int i = 0; i < 4; i++ ) {
			recorder.Record( 0, 0, time, element, 0.5, 0.5 );
			time += length;
		}
		recorder.OutputAudioFile( path + "wtwdt6.wav" );
	}

	{
		const SoundElement32* element;

		// melody 
		AudioRecorder32 recorder( 2, 1 );
		time = 0.0;
		length = 1.0 / 3.0;
		Note::MidiNumber notes[] = { 
			Note::B_4, Note::CSharp_5, Note::FSharp_5, 
			Note::B_5, Note::A_5, Note::D_5,
			Note::CSharp_5, Note::FSharp_5, Note::B_4,
			Note::B_4, Note::D_5, Note::E_5,
		};
		double powerOfX = 2.9;
		double adjuster = 1.6;

		const WaveFunction& func = WaveFunctionFactory::CreateXSinX( powerOfX, 2 * length );
		const WaveTable& dynamicsTable = WaveTableFactory::Create( func, adjuster );
		for ( int i = 0; i < sizeof ( notes ) / sizeof( Note::MidiNumber ); i++ ) {
			const WaveTable& soundTable = WaveTableFactory::Create( WaveTable::Type_Sine, WellTemperament::GetFrequency( notes[ i ] ) );
			element = SoundElementFactory32::Create( soundTable, dynamicsTable, length );
			recorder.Record( 0, 0, time, element, 0.5, 0.5 );
			time += length;
		}
		
		recorder.OutputAudioFile( "wtwdt7.wav" );
	}

	{
		const SoundElement32* element;

		// melody 
		AudioRecorder32 recorder( 2, 1 );
		time = 0.0;
		length = 1.0 / 3.0;
		Note::MidiNumber notes[] = { 
			Note::B_4, Note::CSharp_5, Note::FSharp_5, 
			Note::B_5, Note::A_5, Note::D_5,
			Note::CSharp_5, Note::FSharp_5, Note::B_4,
			Note::B_4, Note::D_5, Note::E_5,
		};
		double powerOfX = 2.9;
		double adjuster = 1.6;

		const WaveFunction& func = WaveFunctionFactory::CreateXSinX( powerOfX, 2 * length, true );
		const WaveTable& dynamicsTable = WaveTableFactory::Create( func, adjuster );
		for ( int i = 0; i < sizeof ( notes ) / sizeof( Note::MidiNumber ); i++ ) {
			const WaveTable& soundTable = WaveTableFactory::Create( WaveTable::Type_Sine, WellTemperament::GetFrequency( notes[ i ] ) );
			element = SoundElementFactory32::Create( soundTable, dynamicsTable, length );
			recorder.Record( 0, 0, time, element, 0.5, 0.5 );
			time += length;
		}

		recorder.OutputAudioFile( path + "wtwdt8.wav" );
	}
}
	
void ExperimetalComposer::SubCompose_001( const std::string& path )
{
	{
		const SoundElement32* element;

		// melody 
		AudioRecorder32 recorder( 2, 1 );
		double time = 0.0;
		double length = 1.0 / 3.0;
		Note::MidiNumber notes[] = { 
			Note::B_4, Note::CSharp_5, Note::FSharp_5, 
			Note::B_5, Note::A_5, Note::D_5,
			Note::CSharp_5, Note::FSharp_5, Note::B_4,
			Note::B_4, Note::D_5, Note::E_5,
		};
		double powerOfX = 0.1;
		double adjuster = 1.6;

		const WaveFunction& func = WaveFunctionFactory::CreateLogXSinX( powerOfX, 2 * length, true );
		const WaveTable& dynamicsTable = WaveTableFactory::Create( func, adjuster );
		for ( int i = 0; i < sizeof ( notes ) / sizeof( Note::MidiNumber ); i++ ) {
			const WaveTable& soundTable = WaveTableFactory::Create( WaveTable::Type_Sine, WellTemperament::GetFrequency( notes[ i ] ) );
			element = SoundElementFactory32::Create( soundTable, dynamicsTable, length );
			recorder.Record( 0, 0, time, element, 0.5, 0.5 );
			time += length;
		}
		recorder.OutputAudioFile( path + "logxsinx3.wav" );
	}

	{
		const SoundElement32* element;

		// melody 
		AudioRecorder32 recorder( 2, 1 );
		double time = 0.0;
		double length = 1.0 / 3.0;
		Note::MidiNumber notes[] = { 
			Note::B_4, Note::CSharp_5, Note::FSharp_5, 
			Note::B_5, Note::A_5, Note::D_5,
			Note::CSharp_5, Note::FSharp_5, Note::B_4,
			Note::B_4, Note::D_5, Note::E_5,
		};
		double powerOfX = 2.9;
		double adjuster = 1.6;

		const WaveFunction& func = WaveFunctionFactory::CreateXSinX( powerOfX, 2 * length, true );
		const WaveTable& dynamicsTable = WaveTableFactory::Create( func, adjuster );
		for ( int i = 0; i < sizeof ( notes ) / sizeof( Note::MidiNumber ); i++ ) {
			const WaveTable& soundTable = WaveTableFactory::Create( WaveTable::Type_Sine, WellTemperament::GetFrequency( notes[ i ] ) );
			element = SoundElementFactory32::Create( soundTable, dynamicsTable, length );
			recorder.Record( 0, 0, time, element, 0.5, 0.5 );
			time += length;
		}
		recorder.OutputAudioFile( path + "xsinx.wav" );
	}

	{
		const SoundElement32* element;

		AudioRecorder32 recorder( 2, 1 );
		double time = 0.0;
		double length = 4;
		double powerOfX = 1.0;
		double adjuster = 1.6;

		const WaveFunction& soundFunc = WaveFunctionFactory::CreateSinXVariableCycle( Line::Type_ConcateParabola, 440, 880, 1, length );
//		const WaveFunction& soundFunc = WaveFunctionFactory::CreateSinXVariableCycle( Line::Type_ConvexParabola, 440, 880, 0, length );
//		const WaveFunction& soundFunc = WaveFunctionFactory::CreateSinXVariableCycle( Line::Type_Straight, 440, 880, 0, length );
		const WaveFunction& dynamicsFunc = WaveFunctionFactory::CreateXSinX( powerOfX, 2 * length, true );
		const WaveTable& dynamicsTable = WaveTableFactory::Create( dynamicsFunc, adjuster );
		const WaveTable& soundTable = WaveTableFactory::Create( soundFunc, 1 );

		element = SoundElementFactory32::Create( soundTable, dynamicsTable, length );
		recorder.Record( 0, 0, time, element, 0.5, 0.5 );
		time += length;

		element = SoundElementFactory32::Create( soundTable, dynamicsTable, length );
		recorder.Record( 0, 0, time, element, 0.5, 0.5 );

		recorder.OutputAudioFile( path + "vari_cycle.wav" );
	}

	{
		const SoundElement32* element;

		AudioRecorder32 recorder( 2, 1 );
		double time = 0.0;
		double length = 2;
		double powerOfX = 1.0;
		double adjuster = 1.0;

		const WaveFunction& soundFunc = WaveFunctionFactory::CreateSinXVariableCycle( Line::Type_Straight, 880, 440, 0, length );
		const WaveFunction& dynamicsFunc = WaveFunctionFactory::CreateLogXSinX( powerOfX, 2 * length, false );
		const WaveTable& dynamicsTable = WaveTableFactory::Create( dynamicsFunc, adjuster );
		const WaveTable& soundTable = WaveTableFactory::Create( soundFunc, 1 );

		element = SoundElementFactory32::Create( soundTable, dynamicsTable, length );
		recorder.Record( 0, 0, time, element, 0.5, 0.5 );
		recorder.OutputAudioFile( path + "vari_cycle2.wav" );
	}

	{
		const SoundElement32* element;

		AudioRecorder32 recorder( 2, 1 );
		double time = 0.0;
		double length = 3;
		double powerOfX = 1.0;
		double adjuster = 1.6;

		const WaveFunction& soundFunc = WaveFunctionFactory::CreateSinXVariableCycle( Line::Type_ConcateParabola, 440, 880, 1, length );
		const WaveFunction& dynamicsFunc = WaveFunctionFactory::CreateXSinX( powerOfX, 2 * length, true );
		const WaveTable& dynamicsTable = WaveTableFactory::Create( dynamicsFunc, adjuster );
		const WaveTable& soundTable = WaveTableFactory::Create( soundFunc, 1 );

		element = SoundElementFactory32::Create( soundTable, dynamicsTable, 2 * length );
		recorder.Record( 0, 0, time, element, 0.5, 0.5 );
		recorder.OutputAudioFile( path + std::string( "vari_cycle3.wav" ) );
	}

	{
		const SoundElement32* element;

		AudioRecorder32 recorder( 2, 1 );
		double time = 0.0;
		double length = 6;
		double powerOfX = 0.8;
		double adjuster = 1.6;

		const WaveFunction& soundFunc0 = WaveFunctionFactory::CreateSinPowerOfX( powerOfX, 440 );
		const WaveFunction& soundFunc1 = WaveFunctionFactory::CreateSinPowerOfX( 1.0 / powerOfX, 440 );
		const WaveFunction& dynamicsFunc = WaveFunctionFactory::CreateXSinX( powerOfX, 2 * length, true );
		const WaveTable& dynamicsTable = WaveTableFactory::Create( dynamicsFunc, adjuster );
		const WaveTable& soundTable0 = WaveTableFactory::Create( soundFunc0, 1 );
		const WaveTable& soundTable1 = WaveTableFactory::Create( soundFunc1, 1 );

		element = SoundElementFactory32::Create( soundTable0, dynamicsTable, length );
		recorder.Record( 0, 0, time, element, 0.5, 0.5 );

		element = SoundElementFactory32::Create( soundTable1, dynamicsTable, length );
		recorder.Record( 0, 0, time, element, 0.5, 0.5 );

		recorder.OutputAudioFile( path + "vari_cycle4.wav" );
	}

	{
		const SoundElement32* element;

		AudioRecorder32 recorder( 2, 1 );
		double time = 0.0;
		double length = 6;
		double adjuster = 0.2;

		const WaveTable& dynamicsTable = WaveTableFactory::Create( WaveTable::Type_Constant, 1.0, adjuster );
//		const WaveTable& dynamicsTable = WaveTableFactory::Create( dynamicsFunc, adjuster );
		const WaveTable& soundTable0 = WaveTableFactory::CreateSin( 440, 0.0, adjuster );
		const WaveTable& soundTable1 = WaveTableFactory::CreateSin( 441, 0.0, adjuster );

		element = SoundElementFactory32::Create( soundTable0, dynamicsTable, length );
		recorder.Record( 0, 0, time, element, 0.5, 0.5 );

		element = SoundElementFactory32::Create( soundTable1, dynamicsTable, length );
		recorder.Record( 0, 0, time, element, 0.5, 0.5 );

		recorder.OutputAudioFile( path + "vari_cycle5.wav" );
	}

	{
		const SoundElement32* element;

		AudioRecorder32 recorder( 2, 1 );
		double time = 0.0;
		double length = 6;
		double adjuster = 0.2;

		const WaveTable& dynamicsTable = WaveTableFactory::Create( WaveTable::Type_Constant, 1.0, adjuster );
		const WaveTable& soundTable0 = WaveTableFactory::CreateSin( 440, 0.0, adjuster );
		const WaveTable& soundTable1 = WaveTableFactory::CreateSin( 441, 0.25, adjuster );

		element = SoundElementFactory32::Create( soundTable0, dynamicsTable, length );
		recorder.Record( 0, 0, time, element, 0.5, 0.5 );

		element = SoundElementFactory32::Create( soundTable1, dynamicsTable, length );
		recorder.Record( 0, 0, time, element, 0.5, 0.5 );

		recorder.OutputAudioFile( path + "vari_cycle6.wav" );
	}

	{
		const SoundElement32* element;

		AudioRecorder32 recorder( 2, 1 );
		double time = 0.0;
		double length = 6;
		double adjuster = 0.2;

		const WaveTable& dynamicsTable = WaveTableFactory::Create( WaveTable::Type_Constant, 1.0, adjuster );
		const WaveTable& soundTable0 = WaveTableFactory::CreateSin( 440, 0.0, adjuster );
		const WaveTable& soundTable1 = WaveTableFactory::CreateSin( 441, 0.5, adjuster );

		element = SoundElementFactory32::Create( soundTable0, dynamicsTable, length );
		recorder.Record( 0, 0, time, element, 0.5, 0.5 );

		element = SoundElementFactory32::Create( soundTable1, dynamicsTable, length );
		recorder.Record( 0, 0, time, element, 0.5, 0.5 );

		recorder.OutputAudioFile( path + "vari_cycle7.wav" );
	}

	{
		const SoundElement32* element;

		// melody 
		AudioRecorder32 recorder( 2, 1 );
		double time = 0.0;
		double length = 4;
		double powerOfX = 2.9;
		double adjuster = 0.6;

		const WaveFunction& func = WaveFunctionFactory::CreateXSinX( powerOfX, 2 * length, false );
		const WaveTable& dynamicsTable = WaveTableFactory::Create( func, adjuster );

		{
			const WaveTable& soundTable = WaveTableFactory::Create( WaveTable::Type_Sine, 220  );
			element = SoundElementFactory32::Create( soundTable, dynamicsTable, length );
			recorder.Record( 0, 0, time, element, 0.5, 0.5 );
		}
		{
			const WaveTable& soundTable = WaveTableFactory::Create( WaveTable::Type_Sine, 220 * 3. / 2 );
			element = SoundElementFactory32::Create( soundTable, dynamicsTable, length );
			recorder.Record( 0, 0, time, element, 0.5, 0.5 );
		}
		{
			const WaveTable& soundTable = WaveTableFactory::Create( WaveTable::Type_Sine, 220 * ( 3. / 2 ) * ( 3. / 2 ) );
			element = SoundElementFactory32::Create( soundTable, dynamicsTable, length );
			recorder.Record( 0, 0, time, element, 0.5, 0.5 );
		}
		{
			const WaveTable& soundTable = WaveTableFactory::Create( WaveTable::Type_Sine, 220 * ( 3. / 2. ) * ( 3. / 2. ) * ( 5. / 4. ) );
			element = SoundElementFactory32::Create( soundTable, dynamicsTable, length );
			recorder.Record( 0, 0, time, element, 0.5, 0.5 );
		}
		{
			const WaveTable& soundTable = WaveTableFactory::CreateSin( 440 * ( 3. / 2. ) * ( 5. / 2. ), 0.0, 1.0 );
			element = SoundElementFactory32::Create( soundTable, dynamicsTable, length );
			recorder.Record( 0, 0, time, element, 0.25, 0.25 );
		}
		{
			const WaveTable& soundTable = WaveTableFactory::CreateSin( 8 + 440 * ( 3. / 2. ) * ( 5. / 2. ), 0.5, 1.0 );
			element = SoundElementFactory32::Create( soundTable, dynamicsTable, length );
			recorder.Record( 0, 0, time, element, 0.25, 0.25 );
		}
		time += length;

		{
			const WaveTable& soundTable = WaveTableFactory::Create( WaveTable::Type_Sine, 220 * ( 5. / 3. ) / 2.  );
			element = SoundElementFactory32::Create( soundTable, dynamicsTable, length );
			recorder.Record( 0, 0, time, element, 0.5, 0.5 );
		}
		{
			const WaveTable& soundTable = WaveTableFactory::Create( WaveTable::Type_Sine, 220 * ( 5. / 3. )  );
			element = SoundElementFactory32::Create( soundTable, dynamicsTable, length );
			recorder.Record( 0, 0, time, element, 0.5, 0.5 );
		}
		{
			const WaveTable& soundTable = WaveTableFactory::Create( WaveTable::Type_Sine, 220 * ( 5. / 3. ) * 9. / 4.  );
			element = SoundElementFactory32::Create( soundTable, dynamicsTable, length );
			recorder.Record( 0, 0, time, element, 0.5, 0.5 );
		}
		{
			const WaveTable& soundTable = WaveTableFactory::Create( WaveTable::Type_Sine, 220 * ( 5. / 3. ) * ( 9. / 4. ) * ( 3. / 2. ) );
			element = SoundElementFactory32::Create( soundTable, dynamicsTable, length );
			recorder.Record( 0, 0, time, element, 0.5, 0.5 );
		}

		{
			const WaveTable& soundTable = WaveTableFactory::CreateSin( 8 + 440 * ( 5. / 3. ) * 9. / 4., 0.0, 1.0 );
			element = SoundElementFactory32::Create( soundTable, dynamicsTable, length );
			recorder.Record( 0, 0, time, element, 0.5, 0.5 );
		}
		{
			const WaveTable& soundTable = WaveTableFactory::CreateSin( 440 * ( 5. / 3. ) * 9. / 4., 0.5, 1.0 );
			element = SoundElementFactory32::Create( soundTable, dynamicsTable, length );
			recorder.Record( 0, 0, time, element, 0.5, 0.5 );
		}

		recorder.OutputAudioFile( path + "test.wav" );
	}
}
